package net.alche.sdd.servlet.imp;

import java.util.Set;

import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration;
import javax.servlet.Servlet;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.util.logging.FileHandler;
import java.util.logging.LogManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.jul.JDK14LoggerAdapter;
import java.io.File;
import java.io.IOException;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.http.HttpRequest;
import net.alche.al.util.AC;
import net.alche.al.util.Far;
import net.alche.al.util.M;
import net.alche.sdd.servlet.SddHttpServer;
import net.alche.sdd.servlet.biz.SddApplicatonBiz;

@SuppressWarnings("all")
public class SddHttpServerTomcat {
  public static final Logger logger = LoggerFactory.getLogger(SddHttpServerBase.class);

  String[] packages = null;
  SddServletDispatchBase dispatch = null;
  public SddApplicatonBiz appBiz = new SddApplicatonBiz();

  public SddHttpServerTomcat() {
    dispatch = new SddServletDispatchBase(appBiz);
  }

  public SddHttpServerTomcat(boolean isStart) {
    dispatch = new SddServletDispatchBase(appBiz);
    if (isStart) {
      start();
    }
  }

  public void dispatch(HttpServletRequest request, HttpServletResponse response) {
    String method = request.getMethod();
    String path = request.getRequestURI();
    SddHttpRequestRespTomcat res = new SddHttpRequestRespTomcat(request, response);
    dispatch.dispatch(res.getHttpType(), request.getRequestURI(), res);
  }

  public void start() {
    logger.info("sdd-server starting..");
    appBiz.setConf(initConf());
    String scanPackage = appBiz.getStr("servlet.scanPackage");
    if (!AC.empty(scanPackage)) {
      packages = scanPackage.split(",");
    }
    logger.info("scanPackage[{}]", scanPackage);
    logger.info("load jdbc...");
    appBiz.initSddFatis();

    dispatch.setBean("SddApplicatonBiz", appBiz);
    dispatch.init();
    dispatch.loadBean(packages);
    dispatch.serverStartSuccess();
    logger.info("sdd-server boot success!");
  }

  public Map<String, String> initConf() {
    String json = AC.file.readClassRes("/conf/application.json");
    Map<String, String> mpConf = new HashMap<>();
    Map mp = Far.tl.fromJsonMap(json);
    recurConf(mpConf, mp, null);
    return mpConf;
  }

  public void recurConf(Map<String, String> mpConf, Map par, String parPath) {
    Set<String> keys = par.keySet();
    if (parPath == null) {
      parPath = "";
    } else {
      parPath += ".";
    }
    for (String key : keys) {
      Object obj = par.get(key);
      if (obj == null)
        continue;
      if (obj instanceof Map) {
        recurConf(mpConf, (Map) obj, parPath + key);
      } else {
        mpConf.put(parPath + key, obj.toString());
      }
    }
  }

  public static void initLogger() {
    try {
      LogManager.getLogManager()
          .readConfiguration(FileUtil.getInputStream(new File(AC.system.getClassPath() + "conf/logging.properties")));
    } catch (Exception e) {
      e.printStackTrace();
    }
    // logger.error("erro-2111");
    // log4j2
    // Configurator.initialize("Log4j2", "classpath:conf/log4j2.xml");
  }
}
